#pragma once

#ifndef Uses_h
#define Uses_h

#include <vector>
#include <map>
#include "Type.h"

class Uses{

private:
	typedef	std::map<Type::Index::Line, Type::List::Var> LVarTableType;
	typedef std::map<Type::Index::Var, Type::Map::EntityLine> LineTableType;
	typedef	std::map<Type::Index::Proc, Type::List::Var> PVarTableType;
	typedef std::map<Type::Index::Var, Type::List::Proc> ProcTableType;

	LVarTableType usesLVarTable;
	LineTableType usesLineTable;
	PVarTableType usesPVarTable;
	ProcTableType usesProcTable;
	Type::Map::Bit usesLineBitMap;
	Type::Map::Bit usesProcBitMap;

	const static Type::Entity::Line allLineType = Type::Entity::ALL_LINE_ENTITY;
public:
	Uses(void);
	~Uses(void);
	void clear();

	// set line uses relationship for the given line , entity and variable, returns status of operation
	bool setLineUses(Type::Index::Line, Type::Entity::Line, Type::Index::Var);
	// set proc uses relationship for the given proc and variable, returns status of operation
	bool setProcUses(Type::Index::Proc proc, Type::Index::Var var);
	// set the bitmap (square matrix) for line uses relationship, returns status of operation
	bool setLineUsesBitMap(Type::Map::Bit&);
	// set the bitmap (square matrix) for proc uses relationship, returns status of operation
	bool setProcUsesBitMap(Type::Map::Bit&);

	// get all used variables
	const Type::List::Var& getUsedVars();
	// get the list of variables used by the given line
	const Type::List::Var& getUsedVarsByLine(Type::Index::Line);
	// get the list of variables used by the given proc
	const Type::List::Var& getUsedVarsByProc(Type::Index::Proc);

	// get the list of lines that uses the given variable
	const Type::List::Line& getLinesUse(Type::Index::Var);
	// get the list of lines with given entity that uses the given variable
	const Type::List::Line& getLinesUse(Type::Index::Var, Type::Entity::Line);
	// get the list of procs that uses the given variable
	const Type::List::Proc& getProcsUse(Type::Index::Var);

	// check if the given line uses the given variable 
	bool isLineUses(Type::Index::Line, Type::Index::Var);
	// check if the given line uses the given variable 
	bool isProcUses(Type::Index::Proc, Type::Index::Var);

	// check if the given variable exists in line
	bool isVarExistsInLine(Type::Index::Var);
	// check if the given line exists in var
	bool isLineExistsInVar(Type::Index::Line);
	// check if the given variable exists in proc
	bool isVarExistsInProc(Type::Index::Var);
	// check if the given proc exists in var
	bool isProcExistsInVar(Type::Index::Proc);
};
#endif